package cn.lg.soar.boot.fc.service.impl;

import cn.lg.soar.boot.client.entity.ClientUser;
import cn.lg.soar.boot.client.service.ClientUserService;
import cn.lg.soar.boot.fc.entity.*;
import cn.lg.soar.boot.fc.entity.vo.FinanceExcelVo;
import cn.lg.soar.boot.fc.entity.vo.RoomVo;
import cn.lg.soar.boot.fc.service.*;
import cn.lg.soar.common.data.msg.I18n;
import cn.lg.soar.common.model.HttpResult;
import cn.lg.soar.common.util.AssertUtil;
import cn.lg.soar.core.util.easyexcel.ExcelUtil;
import cn.lg.soar.database.query.QueryParams;
import cn.lg.soar.database.query.SqueryWapper;
import cn.lg.soar.system.auth.entity.User;
import cn.lg.soar.system.auth.service.IUserService;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import cn.lg.soar.database.base.service.impl.BaseServiceImpl;
import cn.lg.soar.boot.fc.mapper.FinanceMapper;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 财务表
 * @author ZhuanZ（无密码）
 * @since 2025-01-18
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Service
public class FinanceServiceImpl extends BaseServiceImpl<FinanceMapper, Finance> implements FinanceService {

    @Autowired
    protected TenancyRoomService tenancyRoomService;
    @Autowired
    protected TenancyRoomRecordService recordService;
    @Resource
    private RoomService roomService;
    @Autowired
    protected LeaseService leaseService;
    @Autowired
    protected CostService costService;
    @Autowired
    protected IUserService userService;
    /** 客户端用户信息服务 */
    @Autowired private ClientUserService clientUserService;

    private SqueryWapper<Lease> squeryWapper;

    private SqueryWapper<User> squeryWapperUser;

    /**
     * 账单缴费
     */
    @Transactional
    public HttpResult<Void> billPayment(Finance finance) {
        if(finance.getPayAmount().compareTo(finance.getBillAmount()) == 1){
            return HttpResult.fail("B0000", I18n.build("缴费金额大于账单金额！"));
        }
        LocalDateTime now = LocalDateTime.now();
        finance.setUnpaidAmount(finance.getBillAmount().subtract(finance.getPayAmount()));
        finance.setPayTime(now);
        Integer isPaid = 0;
        if(finance.getUnpaidAmount().compareTo(new BigDecimal(0)) == 0){
            isPaid = 1;
            finance.setIsPaid(1);
        }
        AssertUtil.isTrue(super.updateById(finance), "更新失败");
        finance = super.getById(finance.getId());
        if(isPaid == 1){
            TenancyRoom tenancyRoom = tenancyRoomService.getById(finance.getTenancyId());
            if (null == tenancyRoom){
                return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
            }
            LocalDateTime endTime = now;
            if(tenancyRoom.getPayWay() == 0){
                endTime = now.plusMonths(1);
            }else if(tenancyRoom.getPayWay() == 1){
                endTime = now.plusMonths(3);
            }else if(tenancyRoom.getPayWay() == 2){
                endTime = now.plusMonths(6);
            }else if(tenancyRoom.getPayWay() == 3){
                endTime = now.plusMonths(12);
            }
            if(finance.getCostType() == 0){
                tenancyRoom.setWaitPay(new BigDecimal(0));
                tenancyRoom.setAlreadyPay(finance.getBillAmount());
                tenancyRoom.setTenancyState(3);
                tenancyRoom.setContinueState(3);
                tenancyRoom.setFirstPayTime(now);
                tenancyRoom.setMoveTime(now);
                tenancyRoom.setEndTime(endTime);
                AssertUtil.isTrue(tenancyRoomService.updateById(tenancyRoom), "更新失败");

                // 新增租房记录
                TenancyRoomRecord record = new TenancyRoomRecord();
                record.setTenancyId(tenancyRoom.getId());
                record.setFormResultId(tenancyRoom.getFormResultId());
                record.setUserId(tenancyRoom.getUserId());
                record.setApplicantId(tenancyRoom.getApplicantId());
                record.setRoomId(tenancyRoom.getRoomId());
                record.setTenancyWay(tenancyRoom.getTenancyWay());
                record.setLeaseId(tenancyRoom.getLeaseId());
                record.setContractId(tenancyRoom.getContractId());
                record.setContractCode(tenancyRoom.getContractCode());
                record.setPayWay(tenancyRoom.getPayWay());
                record.setIsContinue(0);
                record.setPayAmount(tenancyRoom.getAlreadyPay());
                record.setPayTime(now);
                record.setPayMode(finance.getPayMode());
                record.setApplyTime(tenancyRoom.getApplyTime());
                record.setExamineTime(tenancyRoom.getExamineTime());
                record.setMoveTime(tenancyRoom.getMoveTime());
                record.setEndTime(tenancyRoom.getEndTime());
                AssertUtil.isTrue(recordService.save(record), "创建失败");

                // 更新房间使用情况
                if(tenancyRoom.getTenancyWay() == 0){
                    // 更新整租房间使用情况
                    Room room = roomService.getById(tenancyRoom.getRoomId());
                    if(room != null){
                        room.setUseState(2);
                        if(tenancyRoom.getTenancyWay() == 0){
                            room.setIsFull(1);
                        }
                        AssertUtil.isTrue(roomService.updateById(room), "更新失败");
                    }
                }else{
                    // 更新合租房间使用情况
                    Lease lease = leaseService.getById(tenancyRoom.getLeaseId());
                    if(lease != null){
                        lease.setUseState(2);
                        AssertUtil.isTrue(leaseService.updateById(lease), "更新失败");
                    }

                    // 更新合租总房间使用情况
                    if (squeryWapper == null) {
                        squeryWapper = new SqueryWapper<>(Lease.class);
                    }
                    QueryWrapper<Lease> wrapper = Wrappers.query();
                    List<String> f = new ArrayList<>();
                    f.add("roomId-eq~"+tenancyRoom.getRoomId());
                    f.add("useState-in~0~1");
                    squeryWapper.setWhere(f, wrapper);
                    List<Lease> list = leaseService.list(wrapper);
                    if(list.size() == 0){
                        Room room = roomService.getById(tenancyRoom.getRoomId());
                        if(room != null){
                            room.setUseState(2);
                            room.setIsFull(1);
                            AssertUtil.isTrue(roomService.updateById(room), "更新失败");
                        }
                    }
                }
            }else if(finance.getCostType() == 1){
                tenancyRoom.setAlreadyPay(tenancyRoom.getAlreadyPay().add(finance.getBillAmount()));
                tenancyRoom.setWaitPay(new BigDecimal(0));
                tenancyRoom.setTenancyState(3);
                tenancyRoom.setContinueState(3);
                tenancyRoom.setEndTime(endTime);
                AssertUtil.isTrue(tenancyRoomService.updateById(tenancyRoom), "更新失败");

                // 新增租房记录
                TenancyRoomRecord record = new TenancyRoomRecord();
                record.setTenancyId(tenancyRoom.getId());
                record.setFormResultId(tenancyRoom.getFormResultId());
                record.setUserId(tenancyRoom.getUserId());
                record.setApplicantId(tenancyRoom.getApplicantId());
                record.setRoomId(tenancyRoom.getRoomId());
                record.setTenancyWay(tenancyRoom.getTenancyWay());
                record.setLeaseId(tenancyRoom.getLeaseId());
                record.setContractId(tenancyRoom.getContractId());
                record.setContractCode(tenancyRoom.getContractCode());
                record.setPayWay(tenancyRoom.getPayWay());
                record.setIsContinue(1);
                record.setPayAmount(finance.getBillAmount());
                record.setPayTime(now);
                record.setPayMode(finance.getPayMode());
                record.setApplyTime(tenancyRoom.getApplyTime());
                record.setExamineTime(tenancyRoom.getExamineTime());
                record.setMoveTime(now);
                record.setEndTime(tenancyRoom.getEndTime());
                AssertUtil.isTrue(recordService.save(record), "创建失败");
            }
        }
        return HttpResult.success();
    }

    /**
     * 生成账单
     */
    @Transactional
    public HttpResult<Void> generateBill(Finance finance) {
        TenancyRoom tenancyRoom = tenancyRoomService.getById(finance.getTenancyId());
        if (null == tenancyRoom){
            return HttpResult.fail("B0000", I18n.build("租房信息为空！"));
        }
        Cost cost = costService.getById(finance.getExtend1());
        if (null == cost){
            return HttpResult.fail("B0000", I18n.build("收费信息为空！"));
        }
        finance.setUserId(tenancyRoom.getUserId());
        finance.setRoomId(tenancyRoom.getRoomId());
        finance.setTenancyWay(tenancyRoom.getTenancyWay());
        finance.setLeaseId(tenancyRoom.getLeaseId());
        finance.setContractId(tenancyRoom.getContractId());
        finance.setContractCode(tenancyRoom.getContractCode());
        finance.setPayWay(tenancyRoom.getPayWay());
        finance.setUnpaidAmount(finance.getBillAmount());
        finance.setApplyTime(LocalDateTime.now());
        if(cost.getCostType() == 0){
            finance.setCostType(2);
        }else if(cost.getCostType() == 1){
            finance.setCostType(3);
        }else if(cost.getCostType() == 2){
            finance.setCostType(4);
        }else if(cost.getCostType() == 3){
            finance.setCostType(5);
        }else if(cost.getCostType() == 4){
            finance.setCostType(6);
        }
        AssertUtil.isTrue(super.save(finance), "新增失败");
        return HttpResult.success();
    }

    /**
     * 导出/下载模板
     */
    public void exports(List<Finance> list, HttpServletResponse resp) {
        List<FinanceExcelVo> listVo = new ArrayList<>();
        for (Finance record : list) {
            FinanceExcelVo vo = new FinanceExcelVo();
            BeanUtils.copyProperties(record, vo);
            if(record.getRoomId() != null){
                RoomVo roomVo = roomService.getVoData(record.getRoomId());
                String roomInfo = "";
                if(roomVo != null) {
                    roomInfo = roomVo.getCampusEasyVo().getName()+"*"+roomVo.getBuildingEasyVo().getName()+"*"+roomVo.getUnitEasyVo().getName()+"*"
                            +roomVo.getFloorEasyVo().getName()+"*"+roomVo.getRoomCode();
                }
                vo.setRoomInfo(roomInfo);
            }
//            User user = userService.getById(record.getUserId());
//            if(user != null) {
//                vo.setUserName(user.getNickname());
//            }
            ClientUser user = clientUserService.getById(record.getUserId());
            if(user != null) {
                vo.setUserName(user.getUserName());
            }
            String costType = "其他";
            if(record.getCostType() == 0){
                costType = "首租";
            }else if(record.getCostType() == 1){
                costType = "续租";
            }else if(record.getCostType() == 2){
                costType = "物业费";
            }else if(record.getCostType() == 3){
                costType = "水费";
            }else if(record.getCostType() == 4){
                costType = "电费";
            }else if(record.getCostType() == 5){
                costType = "取暖费";
            }
            vo.setCostType(costType);
            vo.setIsPaid(record.getIsPaid() == 1 ? "是" : "否");
            String payMode = "其他";
            if(record.getPayMode() == 0){
                payMode = "微信";
            }else if(record.getPayMode() == 1){
                payMode = "支付宝";
            }else if(record.getPayMode() == 2){
                payMode = "刷卡";
            }else if(record.getPayMode() == 3){
                payMode = "现金";
            }
            vo.setPayMode(payMode);
            listVo.add(vo);
        }
        // 导出
        ExcelUtil.exportExcelHead("账单", listVo, FinanceExcelVo.class, resp);
    }

    /**
     * 导入
     */
    public HttpResult<Void> imports(MultipartFile files) {
        List<FinanceExcelVo> dataList;
        try {
            dataList = EasyExcel.read(files.getInputStream()).head(FinanceExcelVo.class)
                    .sheet()
                    .doReadSync();
        } catch (IOException e) {
            return HttpResult.fail("B0000", I18n.build("数据格式存在问题，无法读取！"));
        }
        if (CollectionUtils.isEmpty(dataList)) {
            return HttpResult.fail("B0000", I18n.build("数据为空！"));
        }

        for (FinanceExcelVo data : dataList) {
            Finance finance = new Finance();
            BeanUtils.copyProperties(data, finance);
//            if (squeryWapperUser == null) {
//                squeryWapperUser = new SqueryWapper<>(User.class);
//            }
//            QueryWrapper<User> wrapper = Wrappers.query();
//            List<String> f = new ArrayList<>();
//            f.add("nickname-eq~"+data.getUserName());
//            squeryWapperUser.setWhere(f, wrapper);
//            List<User> list = userService.list(wrapper);
//            if(!list.isEmpty()){
//                finance.setUserId(list.get(0).getId());
//            }else{
//                break;
//            }

            ClientUser user = clientUserService.getById(data.getUserName());
            if(user != null){
                finance.setUserId(user.getId());
            }else{
                break;
            }

            int costType = 6;
            if(data.getCostType() != null){
                if(data.getCostType().equals("首租")){
                    costType = 0;
                }else if(data.getCostType().equals("续租")){
                    costType = 1;
                }else if(data.getCostType().equals("物业费")){
                    costType = 2;
                }else if(data.getCostType().equals("水费")){
                    costType = 3;
                }else if(data.getCostType().equals("电费")){
                    costType = 4;
                }else if(data.getCostType().equals("取暖费")){
                    costType = 5;
                }
            }
            finance.setCostType(costType);
            finance.setIsPaid((data.getIsPaid() != null && data.getIsPaid().equals("是")) ? 1 : 0);
            int payMode = -1;
            if(data.getPayMode() != null){
                if(data.getPayMode().equals("微信")){
                    payMode = 0;
                }else if(data.getPayMode().equals("支付宝")){
                    payMode = 1;
                }else if(data.getPayMode().equals("刷卡")){
                    payMode = 2;
                }else if(data.getPayMode().equals("现金")){
                    payMode = 3;
                }
            }
            finance.setPayMode(payMode);
            AssertUtil.isTrue(super.save(finance), "新增失败");
        }

        return HttpResult.success();
    }
}
